#ifndef __PROTOCAL_HPP__
#define __PROTOCAL_HPP__


#include <iostream>
#include <string>

const std::string blank_space_sep = " ";


class Request
{
public:
    Request(const int &data1 , const char &op , const int &data2)
        :data1_(data1) , op_(op) , data2_(data2)
        {}

    // 序列化 , 将Request转化为字符串
    std::string Serialize()
    {
        // 字符与字符间用空格隔开
        std::string content = std::to_string(data1_) + blank_space_sep + op_ + blank_space_sep + std::to_string(data2_);
        return content;
    }

    // 反序列化 , 将字符串转化为结构体
    Request(const std::string &content)
    {
        // 1 + 1
        // 提取出数字和操作符
        size_t prev_date_pos = content.find(blank_space_sep);
        size_t back_data_pos = content.rfind(blank_space_sep); // 从后往前找

        data1_ = std::stoi(content.substr(0 , prev_date_pos));
        data2_ = std::stoi(content.substr(back_data_pos));
        op_ = content[prev_date_pos + 1];
    }

    int Get_first() const
    {
        return data1_;
    }

    int Get_second() const
    {
        return data2_;
    }
    
    char Get_op() const
    {
        return op_;
    }

private:
    int data1_;
    char op_;
    int data2_;    
};

enum
{
    Right = 1,
    Division_Zero,
    Mode_Zero,
    No_Operaotr,
};


class Response
{
public:
    Response(const int& result , const int& mode)
    :result_(result) , mode_(mode)
    {} 

    // 序列化
    std::string Serialize()
    {
        std::string content = std::to_string(result_) + blank_space_sep + std::to_string(mode_);
        return content;
    }

    // 反序列化
    Response(const std::string &content)
    {
        size_t blank_pos = content.find(blank_space_sep);
        result_ = std::stoi(content.substr(0 , blank_pos));
        mode_ = std::stoi(content.substr(blank_pos + 1));
    }

    friend std::ostream& operator<<(std::ostream& out , const Response& rep);

private:
    int result_;
    int mode_;
};

std::ostream& operator<<(std::ostream& out , const Response& rep)
{
    if(rep.mode_ == Right)
    {
        out << "the answer is : " << rep.result_;
    }
    else if(rep.mode_ == Division_Zero)
    {
        out << "incorrect operation : Division Zero !!!";
    }
    else if(rep.mode_ == Mode_Zero)
    {
        out << "incorrect operation : Mode Zero !!!";
    }
    else if(rep.mode_ == No_Operaotr)
    {
        out << "incorrect operation : No_Operaotr !!!";
    }
    
    return out;
}

#endif